extends Area2D
class_name 棋子类

@onready var 图像: TextureRect = %"图像"
@onready var selected = %selected

const size:Vector2=Vector2(96,96)
const 汉字数:String="九八七六五四三二一"

#region 棋子特定数据
@export_enum("P","C","R","N","B","A","K",\
			"p","c","r","n","b","a","k") var ID:String
@export_enum("红","黑") var 棋子阵营:String
@export_enum("兵","卒","炮","车","马","相","象","仕","士","帅","将") var 棋子名:String
var 移动向量:Array=[]:get=获取移动向量
var 活动范围:Rect2i:get=获取活动范围
var 障碍向量:Array=[]:get=获取障碍向量
#endregion

var pos:Vector2i
var 棋局:棋局类=null

signal 被选中(棋子)

#region 棋子特定数据的get函数	
func 获取移动向量():return []
	
func 获取活动范围():return Rect2i(Vector2i(0,0),Vector2i(10,9))
	
func 获取障碍向量():return []
#endregion

#region 核心函数
#除了车和炮之外的棋子, 都可使用该算法判断
func 可移动到pos(目标pos:Vector2i)->bool:
	if 活动范围.has_point(目标pos) and (棋局.获取pos棋子(目标pos)==null \
	or 棋局.获取pos棋子(目标pos).棋子阵营!=棋子阵营):
		var 距离向量=目标pos-pos
		for index in range(移动向量.size()):
			if 距离向量==移动向量[index]:
				if 障碍向量.is_empty():
					return true
				var 障碍向量pos:Vector2i=障碍向量[index]+pos
				if 棋局.获取pos棋子(障碍向量pos)==null:
					return true
	return false

func 获取行棋信息(_pos:Vector2i):
	pass
#endregion
	
#region 可移动到pos功能函数
func 与目标之间棋子数(目标pos:Vector2i):
	if 与目标在一条直线(目标pos):
		var 棋子数:int=0
		if 目标pos.x>pos.x:
			for x in range(pos.x+1,目标pos.x):
				if 棋局.棋子棋局[x][pos.y]!=null:
					棋子数+=1
		elif 目标pos.x<pos.x:
			for x in range(目标pos.x+1,pos.x):
				if 棋局.棋子棋局[x][pos.y]!=null:
					棋子数+=1
		elif 目标pos.y>pos.y:
			for y in range(pos.y+1,目标pos.y):
				if 棋局.棋子棋局[pos.x][y]!=null:
					棋子数+=1
		elif 目标pos.y<pos.y:
			for y in range(目标pos.y+1,pos.y):
				if 棋局.棋子棋局[pos.x][y]!=null:
					棋子数+=1
		return 棋子数
	return -1
	
func 与目标在一条直线(目标pos:Vector2i)->bool:
	if (pos.x==目标pos.x and pos.y!=目标pos.y) or (pos.x!=目标pos.x and pos.y==目标pos.y):
		return true
	return false		
#endregion

#region 棋子行棋信息相关
func 同列相同棋子数():
	var 数量:int=0
	for 棋子 in 棋局.board_tile_map.get_children():
		if 棋子.棋子阵营==棋子阵营 and 棋子.棋子名==棋子名 and 棋子.pos.y==pos.y:
			数量+=1
	return 数量
	
func 获取同列时名字():
	return 获取同列时位置()+棋子名
	
func 获取同列index():
	if 棋子阵营=="红":
		return 获取红棋同列index()
	else:
		return 获取黑棋同列index()

func 获取红棋同列index():
	var 同列index:int=0
	for 行 in range(棋局.棋盘max行):
		var 棋子:棋子类=棋局.棋子棋局[行][pos.y]
		if 棋子!=null and 棋子.棋子阵营==棋子阵营 and 棋子.棋子名==棋子名:
			if 棋子==self:
				break
			else:
				同列index+=1
	return 同列index

func 获取黑棋同列index():
	var 同列index:int=0
	for 行 in range(棋局.棋盘max行-1,1,-1):
		var 棋子:棋子类=棋局.棋子棋局[行][pos.y]
		if 棋子!=null and 棋子.棋子阵营==棋子阵营 and 棋子.棋子名==棋子名:
			if 棋子==self:
				break
			else:
				同列index+=1
	return 同列index	
	
func 获取同列时位置():
	var 同列index:int=获取同列index()
	var 位置:String
	if 同列相同棋子数()==2:		#前后
		位置="前后"
	elif 同列相同棋子数()==3:		#前中后
		位置="前中后"
	elif 同列相同棋子数()==4:		#前二三后
		位置="前二三后"
	elif 同列相同棋子数()==5:		#前二三四后
		位置="前二三四后"
	return 位置[同列index]
		
func 获取棋子代称():
	return 棋子名+获取平移列(pos)

func 获取行棋动作(目标pos:Vector2i):
	if 与目标在一条直线(目标pos):
		return 获取直线时行棋动作(目标pos)
	else:
		return 获取斜线时行棋动作(目标pos)
	
func 获取直线时行棋动作(目标pos:Vector2i):
	if 目标pos.x==pos.x:
		return "平"+获取平移列(目标pos)
	elif 棋子阵营=="红":
		if 目标pos.x>pos.x:
			return "退"+获取进退行(目标pos)
		else:
			return "进"+获取进退行(目标pos)
	else:
		if 目标pos.x>pos.x:
			return "进"+获取进退行(目标pos)
		else:
			return "退"+获取进退行(目标pos)
	
func 获取斜线时行棋动作(目标pos:Vector2i):
	if 棋子阵营=="红":
		if 目标pos.x>pos.x:
			return "退"+获取平移列(目标pos)
		elif 目标pos.x<pos.x:
			return "进"+获取平移列(目标pos)
	else:
		if 目标pos.x>pos.x:
			return "进"+获取平移列(目标pos)
		elif 目标pos.x<pos.x:
			return "退"+获取平移列(目标pos)
			
func 获取进退行(目标pos:Vector2i):
	if 棋子阵营=="红":
		return 汉字数[9-abs(目标pos.x-pos.x)]
	else:
		return " "+str(abs(目标pos.x-pos.x))+" "
		
func 获取平移列(目标pos:Vector2i):
	if 棋子阵营=="红":
		return 汉字数[目标pos.y]
	else:
		return " "+str(目标pos.y+1)+" "	
#endregion

#region 棋子中状态相关
func 显示被选中():
	selected.show()
	
func 恢复正常显示():
	selected.hide()

func _on_input_event(_viewport: Node, event: InputEvent, _shape_idx: int) -> void:
	if event.is_action_pressed("mouse_left"):
		被选中.emit(self)
#endregion
